// com.example.demo.registrar.MyServiceRegistrar
package com.rain.rainspringboot3.beanDefinitionRegistrar.registrar;


import com.rain.rainspringboot3.beanDefinitionRegistrar.annotation.MyService;
import com.rain.rainspringboot3.beanDefinitionRegistrar.proxy.MyServiceProxyFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;

import java.util.Map;
import java.util.Set;

/**
 * @author rain
 */
public class MyServiceRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 获取 basePackages
        String[] basePackages = getBasePackages(importingClassMetadata);

        // 自定义扫描器
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(MyService.class));

        for (String basePackage : basePackages) {
            Set<BeanDefinition> candidates = scanner.findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                String beanClassName = candidate.getBeanClassName();
                if (beanClassName == null) {
                    continue;
                }

                // 注册 FactoryBean，用于创建代理
                GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
                beanDefinition.setBeanClass(MyServiceProxyFactory.class);
                // 传入目标类名
                beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
                beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);

                String beanName = generateBeanName(beanClassName);
                if (!registry.containsBeanDefinition(beanName)) {
                    registry.registerBeanDefinition(beanName, beanDefinition);
                }
            }
        }
    }

    private String[] getBasePackages(AnnotationMetadata metadata) {
        // 从 @EnableMyServices 中读取 basePackages
        Map<String, Object> attributes = metadata.getAnnotationAttributes(
            "com.rain.rainspringboot3.beanDefinitionRegistrar.enable.EnableMyServices"
        );
        String[] basePackages = (String[]) attributes.get("basePackages");
        if (basePackages.length == 0) {
            // 默认使用 @EnableMyServices 所在包
            return new String[]{ClassUtils.getPackageName(metadata.getClassName())};
        }
        return basePackages;
    }

    private String generateBeanName(String className) {
        int idx = className.lastIndexOf('.');
        String simpleName = className.substring(idx + 1);
        // 首字母小写作为 bean name，符合 Spring 默认规则
        return Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
    }
}